/*************************************************
Author: will
Date: 8/23/2012
Description:
Notes: 
*************************************************/

#ifndef __CBattleRole_h__
#define __CBattleRole_h__

#include "CBattleData.h"
#include "CBattleBuff.h"

class CSkill;
class CSkillEffect;

class CRoleSkillUnit
{
public:
    CRoleSkillUnit() 
    {
        Clear();
    }

    void Clear()
    {
        _iTurn = 0;
        _iRoleID = -1;
        _uiSkillID = 0;
    }

    virtual ~CRoleSkillUnit() 
    {
    }

    void NewTurn(){--_iTurn;}

    int GetTurn() const {return _iTurn;}
    int GetRoleID() const {return _iRoleID;}
    unsigned int GetSkillID() const {return _uiSkillID;}

    void SetTurn(int iTurn){_iTurn = iTurn;}
    void SetRoleID(int iRoleID){_iRoleID = iRoleID;}
    void SetSkillID(unsigned int uiSkillID){_uiSkillID = uiSkillID;}

private:
    int                 _iTurn;
    int                 _iRoleID;       //此技能来源角色ID
    unsigned int        _uiSkillID;
};

class CRoleSkillList
{
public:
    CRoleSkillList() 
    {
        Clear();
    }

    void Clear()
    {
        _astSkillList.Clear();
    }

    virtual ~CRoleSkillList() 
    {
    }

    int GetSkillSize() const {return _astSkillList.Size();}

    CRoleSkillUnit& GetSkillUnit(int iIndex){return _astSkillList[iIndex];}

    void AddSkillUnit(CRoleSkillUnit& stUnit)
    {
        _astSkillList.AddOneItem(stUnit);
    }

    int DelSkillUnit(int iIndex)
    {
        return _astSkillList.DelOneItem(iIndex);
    }

private:
    CTLib::CTArray<CRoleSkillUnit, MAX_BATTLE_ROLE_SKILL_COUNT> _astSkillList;
};

class CBattleRole
{
    friend class CBattleVideo;
    friend class CBattleRules;
public:
    enum ENUM_COURAGE_STAT_TAG
    {
        COURAGE_STAT_NORMAL         = 0,    //状态正常
        COURAGE_STAT_FALL_BACK      = 1,    //立即撤退
        COURAGE_STAT_TURN_WAIT      = 2,    //回合等待
        COURAGE_STAT_RECV_ACT       = 3,    //勇气恢复并出击
    };
    enum ENUM_ANGER_STAT_TAG
    {
        ANGER_STAT_NORMAL         = 0,    //状态正常
        ANGER_STAT_FULL           = 1,    //怒气已满
    };

    CBattleRole()
    {
    }

    virtual ~CBattleRole()
    {
    }

    int InitBattleRole(int iID, CBattleRoleData& stBattleRoleDate);

    void DumpRoleInfo(bool bIsTurnBegin);

    int GetRoleID() {return _iID;}
    int GetLevel() {return _stRoleBase._shLevel;}
    int GetTurnOrderValue()
    {
        return _stRoleBase.HasDead() ?
            0 : _stRoleBase._stAttr.GetAttr(EXT_ATTR_TURN_ORDRE);
    }
    int GetGridIndex() {return _stRoleBase.HasDead() ? -1 : _iGridPos;}
    int GetRelatGridIndex(bool bLeftSide)
    {
        return _stRoleBase.HasDead() ?
            -1 : (bLeftSide ? _iGridPos : MAX_BATTLE_GRIDS - 1 - _iGridPos);
    }
    int GetOriginalPos() {return _stRoleBase._iGridPos;}
    void SetGridIndex(int iIndex) {_iGridPos = iIndex;}
    bool HasDead() {return _stRoleBase.HasDead();}
    bool IsAngerOpen() const {return _stRoleBase._bAngerOpen;}
    bool IsLeft() {return _stRoleBase._bIsLeft;}
    bool IsPlayerObject() const
    {
        return GAME_OBJ_TYPE_PLAYER == _stRoleBase._chType;
    }
    bool IsPartnerObject() const
    {
        return GAME_OBJ_TYPE_PARTNER == _stRoleBase._chType;
    }
    bool IsMonsterObject() const
    {
        return GAME_OBJ_TYPE_MONSTER == _stRoleBase._chType;
    }

    int GetHP() const {return _stRoleBase._iHP;}
    void SetHP(int iHP) {_stRoleBase._iHP = iHP;}
    int GetHPMax() const {return _stRoleBase._iHPMax;}
    int GetHPBeforeAtk() const {return _iHPBeforeAtk;}
    void SetHPBeforeAtk(int iVal) {_iHPBeforeAtk = iVal;}

    unsigned char GetCareer() const {return _stRoleBase._ucCareer;}
    unsigned char GetAtkOrder() {return _stRoleBase._ucOrder;}
    CPlayerAttr& GetBattleAttr(){return _stBattleAttr;}
    CPlayerAttr& GetTurnMainAttr(){return _stTurnMainAttr;}
    CPlayerAttr& GetTurnMinorAttr(){return _stTurnMinorAttr;}
    CPlayerAttr& GetBaseAttr(){return _stRoleBase._stAttr;}
    CStatusList& GetStatusList(){return _stRoleBase._stStatusList;}
    CBattleRoleData& GetRoleBase(){return _stRoleBase;}

    //秘宝相关
    int RoleAttrChg(int iAttrBefore);

    //预执行技能
    CRoleSkillList& GetPreSkillList(){return _stSkillList;}
    void AddSkillUnit(CRoleSkillUnit& stUnit)
    {
        _stSkillList.AddSkillUnit(stUnit);
    }

    //血量变化
    int ModRoleHP(int iChgValue, int iAttackID);
    int ChgBlood(int& iChgBlood);

    //Buff相关
    bool IsSwim();
    bool IsStick();
    int AddBuff(CSkillEffect& stSkillEffect, int iSrcType, int iSrcID);
    bool InDefinitBuff(unsigned char ucStatType, unsigned char ucSubType);
    bool InDefinitSubBuff(unsigned char ucStatType, unsigned char ucSubType, int iData);
    int CalcBuffAddAttr(CPlayerAttr& stPlayerAttr);
    int CalcBuffBeforeTurn(bool& bTurnOver);
    int DelBuffByStatType(unsigned char ucStatType);
    int DelBuffBySubType(unsigned char ucStatType, unsigned char ucSubType);
    void RoleDelAllBuff();
    void DumpBattleBuffList(){_stBuffList.DumpBattleBuffList();}
    void RoleAddBuffVideo(unsigned int uiEffectID, int iSrcType, int iSrcID,
        int iTurn, int iAddNum);

    //勇气相关
    bool IsNoCourage() const {return _stRoleBase._iCourage <= 0;}
    int GetCourage() const {return _stRoleBase._iCourage;}
    int GetCourageMax() const {return _stRoleBase._iCourageMax;}
    int ModCourage(int iValue);
    void SetFallBackRightNow() {_chCourageStat = COURAGE_STAT_FALL_BACK;}
    bool IsFallBackRightNow() const {return (COURAGE_STAT_FALL_BACK == _chCourageStat);}
    void SetRoleTurnWait();
    bool IsHaveToTurnWait() const {return (COURAGE_STAT_TURN_WAIT == _chCourageStat);}
    void SetRecvCourageAndAct() {_chCourageStat = COURAGE_STAT_RECV_ACT;}
    bool IsRecvCourageAndAct() const {return (COURAGE_STAT_RECV_ACT == _chCourageStat);}
    void SetCourageNormal() {_chCourageStat = COURAGE_STAT_NORMAL;}
    int RecvCourageAndAct();
    
    //怒气相关
    int ModAnger(int iValue);
    int GetAnger() {return _stRoleBase._iAnger;}
    int GetUseAnger(){return _iUseAnger;}
    int GetAngerMax() const {return _stRoleBase._iAngerMax;}
    bool IsAngerNormal() const {return ANGER_STAT_NORMAL == _chAngerStat;}
    void SetAngerNormal(){_chAngerStat = ANGER_STAT_NORMAL;}
    bool IsAngerFull() const {return ANGER_STAT_FULL == _chAngerStat;}
    void SetAngerFull(){_chAngerStat = ANGER_STAT_FULL;}

    //释放技能
    int CastSkill(CSkill& stSkill);
    
    bool CanCastSkill(CSkill& stSkill)
    {
        if (stSkill.GetID() <= 0)
        {
            return false;
        }

        int64 i64ValueTmp =
            INT64_1 * _stRoleBase._iHP * stSkill.GetUseHPPercent();
        i64ValueTmp /= BATTLE_RATE_SKILL_PERCENT;
        int iHPUse = (int)(i64ValueTmp);
        if (iHPUse < 0)
        {
            iHPUse = 0 - iHPUse;
        }
        if (_stRoleBase._iHP < iHPUse)
        {
            return false;
        }

        if (stSkill.GetUseAnger() > 0)
        {
            return (_stRoleBase._iAnger >= stSkill.GetUseAnger());
        }

        return true;
    }

    bool CanCastNormalSkill()
    {
        return CanCastSkill(_stRoleBase._stNormalSkill);
    }

    bool CanCastMagicSkill()
    {
        return CanCastSkill(_stRoleBase._stMagicSkill);
    }
    
    void GetNormalSkill(CSkill& stSkill) {stSkill = _stRoleBase._stNormalSkill;}
    void GetMagicSkill(CSkill& stSkill) {stSkill = _stRoleBase._stMagicSkill;}

    int GetHasDoNormalAtkCount()const {return _iHasDoNormalAtkCount;}
    void AddHasDoNormalAtkCount() {_iHasDoNormalAtkCount++;}
    void CleanHasDoNormalAtkCount() {_iHasDoNormalAtkCount = 0;}

    int GetTypeAttr(unsigned char ucType)
    {
        return _stRoleBase._stAttr.GetAttr(ucType) +
               _stBattleAttr.GetAttr(ucType);
    }

    int GetTypeAttr(unsigned char ucType, bool bIsMain)
    {
        if (bIsMain)
        {
            return  _stRoleBase._stAttr.GetAttr(ucType) +
                    _stBattleAttr.GetAttr(ucType) +
                    _stTurnMainAttr.GetAttr(ucType);
        }
        else
        {
            return  _stRoleBase._stAttr.GetAttr(ucType) +
                    _stBattleAttr.GetAttr(ucType) +
                    _stTurnMinorAttr.GetAttr(ucType);
        }
    }

private:
    char                _chCourageStat;             //关于勇气的状态(0正常 1立即撤退 2回合等待 3恢复勇气并出击)
    char                _chAngerStat;               //关于怒气的状态(0正常 1已满)
    int                 _iID;                       //战场角色唯一ID，也是下标
    int                 _iGridPos;                  //当前位置(从0开始)
    int                 _iHasDoNormalAtkCount;      //累计执行了几次普通攻击
    int                 _iUseAnger;                 //释放本次高阶技能消耗的怒气
    int                 _iHPBeforeAtk;              //被攻击前的血量 当前主要用于恶魔之牙反弹伤害

    CRoleSkillList      _stSkillList;               //预执行技能列表

    CPlayerAttr         _stBattleAttr;              //战斗加成数据 记录status等战斗时(非面板显示)加成二级属性
    CPlayerAttr         _stTurnMainAttr;            //回合主数据 记录Buff及预处理加成二级属性
    CPlayerAttr         _stTurnMinorAttr;           //回合辅数据 记录Buff及预处理加成二级属性

    CBattleBuffList     _stBuffList;                //Buff列表
    CBattleRoleData     _stRoleBase;                //当前数据
};

class CBattleRoles
{
    friend class CBattleVideo;
public:
    CBattleRoles() 
    {
    }

    virtual ~CBattleRoles() 
    {
    }

    void ClearRoleSize() {_astRoles.Clear();}
    int AddBattleRole(CBattleRoleData& stBattleRoleData);
    
    int InitBattleRoundCtrl();
    int GetTotalTurnOrder(bool& bIsLeftFirst);

    void CalcBattleTotalHP(bool bIsLeft, int& iTotalNow, int& iTotalMax);

    int GetRoleCount() const {return _astRoles.Size();}
    int GetRole(int iRoleID, CBattleRole& stBattleRole);
    CBattleRole& GetRole(int iRoleID);
    CBattleRoleData& GetRoleBase(int iRoleID);

    int GetLivingRoleCount(bool bIsLeft);

    bool IsValidRoleID(int iRoleID) const
    {
        return (iRoleID >= 0 && iRoleID < _astRoles.Size());
    }

    bool GetRightDeadBomb() const {return _bRightDeadBomb;}
    void SetRightDeadBomb(bool bVal) {_bRightDeadBomb = bVal;}

    void DumpRolesInfo();

private:
    bool _bRightDeadBomb;
    CTLib::CTArray<CBattleRole, MAX_BATTLE_ROLES>  _astRoles;
};

#endif // __CBattleRole_h__

